/* eslint-disable */

export const isRawHtml = (htmlString: string) => {
	const rawHtmlRe = /^<[a-z\d]+\s*(style=)?>/i;
	return rawHtmlRe.test(htmlString);
};

export const isHtmlSerialize = (htmlString: string) => {
	const rawHtmlRe = /^&lt;\s*[a-z\d]+\s*(style=)?/i;
	return rawHtmlRe.test(htmlString);
};

export class HtmlSerializer {
	static isRawHtml = isRawHtml;
	static isHtmlSerialize = isHtmlSerialize;

	static xmls = new XMLSerializer();
	static dom = new DOMParser();
	static div = document.createElement("div");
	static text = document.createTextNode("");

	static SingleInstance: HtmlSerializer = null;

	constructor() {
		if (HtmlSerializer !== null) {
			return HtmlSerializer.SingleInstance;
		}
		HtmlSerializer.SingleInstance = this;
	}

	serializeToString(input: Element | Node) {
		return HtmlSerializer.xmls.serializeToString(input);
	}

	/**
	 * 用于将><转换为转移字符
	 *
	 * < = `&lt;` > = `&gt;` & = `&amp;` ' = &apos; " = &quot;
	 *
	 * @param input 一个dom结点、Element、String
	 */
	encodeHTML(input: Element | Node | string): string {
		let inputStr: string = input as string;
		if (typeof inputStr !== "string") {
			inputStr = this.serializeToString(inputStr);
		}
		let preData = HtmlSerializer.text.data;
		let preHtml = HtmlSerializer.div.innerHTML;
		try {
			HtmlSerializer.text.data = inputStr;
			HtmlSerializer.div.append(HtmlSerializer.text);
			let nodeStr = HtmlSerializer.div.innerHTML;

			return nodeStr
				.replace(/\n/g, "")
				.replace(/"/g, "&quot;")
				.replace(/'/g, "&apos;"); //.replace(/&/g, "&amp;");
		} catch (exx) {
			console.log(exx);
			return null;
		} finally {
			HtmlSerializer.text.data = preData;
			HtmlSerializer.div.innerHTML = preHtml;
		}
	}

	decodeToHtmlString(input: string): string {
		let bodyText = input;

		if (isHtmlSerialize(input)) {
			let doc = HtmlSerializer.dom.parseFromString(input, "text/html");
			bodyText = doc.body.innerText;
		}

		return bodyText.replace(/&quot;/g, `"`).replace(/&apos;/g, "'");
	}

	decodeHTML(input: string): DocumentFragment {
		let bodyText = this.decodeToHtmlString(input);
		let docNodeContainer = HtmlSerializer.dom.parseFromString(
			bodyText,
			"text/html"
		);
		let bodyNode = docNodeContainer.body;
		let frag = document.createDocumentFragment();

		while (bodyNode.firstChild !== null) {
			frag.append(bodyNode.firstChild);
		}

		return frag;
	}
}
